home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*------------------------------------------------------------------------------
- *
- * OORT - vehicle.c - Routines for controlling the vehicle.
- *
- * $Id: vehicle.c,v 1.5 1994/02/08 00:10:51 jimh Exp $
- *
- * Chris Fouts - April, 1993.
- *
- *----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-
- #include <pf.h>
- #include <prmath.h>
- #include <pfutil.h>
-
- #include "oort.h"
- #include "dashboard.h"
- #include "vehicle.h"
-
- /* BEGIN PROTOTYPES -S vehicle.c */
- static void adjustSpeed( void ) ;
- static void turnVehicle( float fraction ) ;
- /* END PROTOTYPES -S vehicle.c */
-
- #define GRAVITY (7.5f) /* Meters/sec/sec */
-
- #define ONE_THIRD (1.0f/3.0f)
- #define TWO_THIRDS (2.0f/3.0f)
-
- #define TURN_DEG_PER_SEC (45.0f)
-
- static float accel ;
- extern int debugOn ;
- extern int markPoint ;
- extern Wheel wheel[3] ;
- extern Player player[1] ;
- extern pfVec3 up ;
- extern pfVec3 ahead ;
- extern pfVec3 right ;
- extern float speed ;
- extern float power ;
- extern float mouseX ;
- extern float mouseY ;
- extern float gameTime ; /* game time */
- extern float eTime ; /* elapsed time */
- extern int braking ;
- extern int pausing ;
- extern int landing ;
- extern int orbitalActive ;
- extern Motion motion ;
- extern float idleStartTime ;
-
- extern float accelFactor ;
- extern float topSpeed ;
-
-
- /*------------------------------------------------------------------------------
- * Correct the location of the wheels.
- *----------------------------------------------------------------------------*/
- void
- updateWheels(
- void
- )
- {
- pfVec3 v ;
-
- ADDSCALE_VEC3( wheel[FRONT_WHEEL].xyz, motion.cg,
- (float)(TWO_THIRDS*CAR_LENGTH), ahead );
-
- ADDSCALE_VEC3( v, motion.cg, -(float)(ONE_THIRD*CAR_LENGTH), ahead ) ;
-
- ADDSCALE_VEC3( wheel[RREAR_WHEEL].xyz, v, (float)(0.5f*CAR_WIDTH),
- right ) ;
-
- ADDSCALE_VEC3( wheel[LREAR_WHEEL].xyz, v, -(float)(0.5f*CAR_WIDTH),
- right ) ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Turn the vehicle.
- *----------------------------------------------------------------------------*/
- static void
- turnVehicle(
- float fraction
- )
- {
- int i ;
- float sv ;
- float sta ;
- float cta ;
- pfVec3 r ;
- pfVec3 a ;
-
- if( wheel[FRONT_WHEEL].inAir == 0 || landing )
- {
- if( landing )
- {
- pfSinCos( fraction * TURN_DEG_PER_SEC * eTime,
- &sta, &cta ) ;
- }
- else if( speed > 0.0f )
- {
- pfSinCos( fraction * TURN_DEG_PER_SEC * eTime *
- ( 0.25 + speed / topSpeed ), &sta, &cta ) ;
- }
- else if( speed < 0.0f )
- {
- pfSinCos( fraction * TURN_DEG_PER_SEC * eTime *
- ( 0.25 - speed / topSpeed ), &sta, &cta ) ;
- }
- else if( !braking )
- {
- pfSinCos( fraction * TURN_DEG_PER_SEC * eTime * 0.50f,
- &sta, &cta ) ;
- }
- else
- {
- return ;
- }
-
- PFCOPY_VEC3( r, right ) ;
- PFCOPY_VEC3( a, ahead ) ;
-
- PFCOMBINE_VEC3( right, cta, r, -sta, a ) ;
- PFCOMBINE_VEC3( ahead, sta, r, cta, a ) ;
-
- updateWheels() ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Update the speed.
- *----------------------------------------------------------------------------*/
- static void
- adjustSpeed(
- void
- )
- {
- float pr ;
- float newSpeed ;
-
- if( wheel[FRONT_WHEEL].inAir + wheel[RREAR_WHEEL].inAir +
- wheel[LREAR_WHEEL].inAir != 3 )
- {
- newSpeed = speed + eTime * accel ;
- /*
- * Stop at 0.0 so we can come to a standstill.
- */
- if( newSpeed * speed < 0.0f )
- {
- speed = 0.0f ;
- }
- else
- {
- if( newSpeed > topSpeed )
- {
- speed = topSpeed ;
- }
- else if( newSpeed < -0.5f * topSpeed )
- {
- speed = -0.5f * topSpeed ;
- }
- else
- {
- speed = newSpeed ;
- }
- }
- accel = 0.0f ;
- }
-
- pr = speedPowerReq() ;
- if( pr > power )
- speed *= power / pr ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Determine the intersection point with the ground.
- *----------------------------------------------------------------------------*/
- void
- getDistanceToGround(
- pfGroup *node,
- pfVec3 intersection[3],
- pfVec3 n[3],
- pfVec3 pt0,
- pfVec3 pt1,
- pfVec3 pt2
- )
- {
- int i ;
- long k ;
- pfVec3 center ;
- pfVec3 v[3] ;
- pfSegSet segSet ;
- pfSeg iSegs[3] ;
- pfSeg *segs[3] ;
- pfHit **hits[3] ;
-
- PFSET_VEC3( center, 0.0f, 0.0f, 0.0f ) ;
- PFSCALE_VEC3( v[0], 1.5f, pt0 ) ;
- pfMakePtsSeg( &iSegs[0], v[0], center ) ;
-
- PFSCALE_VEC3( v[1], 1.5f, pt1 ) ;
- pfMakePtsSeg( &iSegs[1], v[1], center ) ;
-
- PFSCALE_VEC3( v[2], 1.5f, pt2 ) ;
- pfMakePtsSeg( &iSegs[2], v[2], center ) ;
-
- segSet.segs[0] = iSegs[0] ;
- segSet.segs[1] = iSegs[1] ;
- segSet.segs[2] = iSegs[2] ;
- segSet.activeMask = 0x07 ;
- segSet.mode = PFTRAV_IS_PRIM | PFTRAV_IS_NORM ;
- segSet.isectMask = GROUND_MASK ;
- segSet.bound = NULL ;
- segSet.discFunc = NULL ;
- segSet.userData = NULL ;
-
- k = pfSegsIsectNode( node, &segSet, hits ) ;
-
- for( i = 0 ; i < 3 ; i++ )
- {
- pfVec3 point ;
- long flags ;
-
- pfQueryHit( hits[i][0], PFQHIT_FLAGS, &flags ) ;
- if( flags & PFHIT_POINT )
- {
- pfQueryHit( hits[i][0], PFQHIT_POINT, point ) ;
- PFCOPY_VEC3( intersection[i], point ) ;
- }
- else
- {
- PFCOPY_VEC3( intersection[i],
- ( i == 0 ) ? pt0 : ( ( i == 1 ) ? pt1 : pt2 ) ) ;
- }
- if( flags & PFHIT_NORM )
- {
- pfQueryHit( hits[i][0], PFQHIT_NORM, point ) ;
- PFCOPY_VEC3( n[i], point ) ;
- }
- else
- {
- PFCOPY_VEC3( n[i], intersection[i] ) ;
- pfNormalizeVec3( n[i] ) ;
- }
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Move own vehicle one frame.
- *----------------------------------------------------------------------------*/
- void
- moveSelf(
- pfGroup *node
- )
- {
- int i ;
- float sn ;
- float va ;
- float vr ;
- float vu ;
- float f ;
- pfVec3 u ;
- pfVec3 oldVel ;
- pfVec3 d ;
- pfVec3 g ;
- pfVec3 n[3] ;
- pfVec3 v[3] ;
- int wheelsOnGround ;
- static int airBorne = 0 ;
- static int idleFlag = 0 ;
-
- /*
- * Check to turn vehicle.
- */
- if( mouseX < -0.2f )
- {
- turnVehicle( ( mouseX + 0.2f ) / 0.8f ) ;
- }
- else if( mouseX > 0.2f )
- {
- turnVehicle( ( mouseX - 0.2f ) / 0.8f ) ;
- }
-
- /*
- * Advance vehicle.
- */
- adjustSpeed() ;
-
- #ifdef DEBUG
- if( !landing && ABS( speed ) < 0.10f * MAX_SPEED && orbitalActive )
- #else
- if( !landing && ABS( speed ) < 0.10f * MAX_SPEED )
- #endif /* DEBUG */
- {
- if( idleFlag == 0 )
- {
- idleFlag = 1 ;
- idleStartTime = gameTime ;
- }
- }
- else
- {
- idleStartTime = gameTime ;
- }
-
- /*
- * Remove side velocities.
- */
- wheelsOnGround = 0 ;
- for( i = 0 ; i < 3 ; i++ )
- {
- if( !wheel[i].inAir )
- {
- sn = PFDOT_VEC3( wheel[i].vel, right ) ;
- wheel[i].vel[0] -= sn * right[0] ;
- wheel[i].vel[1] -= sn * right[1] ;
- wheel[i].vel[2] -= sn * right[2] ;
- wheelsOnGround++ ;
- }
- }
-
- if( speed == 0.0f && wheelsOnGround == 3 )
- {
- PFSET_VEC3( wheel[FRONT_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
- PFSET_VEC3( wheel[RREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
- PFSET_VEC3( wheel[LREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
- return ;
- }
-
- /*
- * Set velocity component along "ahead" direction equal to
- * "speed".
- */
- f = speed - PFDOT_VEC3( wheel[FRONT_WHEEL].vel, ahead ) ;
- OFFSET_VEC3( wheel[FRONT_WHEEL].vel, f, ahead ) ;
- f = speed - PFDOT_VEC3( wheel[RREAR_WHEEL].vel, ahead ) ;
- OFFSET_VEC3( wheel[RREAR_WHEEL].vel, f, ahead ) ;
- f = speed - PFDOT_VEC3( wheel[LREAR_WHEEL].vel, ahead ) ;
- OFFSET_VEC3( wheel[LREAR_WHEEL].vel, f, ahead ) ;
-
- /*
- * Add gravity effect to wheels.
- */
- PFCOPY_VEC3( g, motion.cg ) ;
- pfNormalizeVec3( g ) ;
- PFSCALE_VEC3( g, -GRAVITY * eTime, g ) ;
- PFADD_VEC3( wheel[FRONT_WHEEL].vel, wheel[FRONT_WHEEL].vel, g ) ;
- PFADD_VEC3( wheel[RREAR_WHEEL].vel, wheel[RREAR_WHEEL].vel, g ) ;
- PFADD_VEC3( wheel[LREAR_WHEEL].vel, wheel[LREAR_WHEEL].vel, g ) ;
-
- /*
- * Move wheels.
- */
- OFFSET_VEC3( wheel[FRONT_WHEEL].xyz, eTime, wheel[FRONT_WHEEL].vel ) ;
- OFFSET_VEC3( wheel[RREAR_WHEEL].xyz, eTime, wheel[RREAR_WHEEL].vel ) ;
- OFFSET_VEC3( wheel[LREAR_WHEEL].xyz, eTime, wheel[LREAR_WHEEL].vel ) ;
-
- /*
- * Check for distance to ground.
- */
- getDistanceToGround( node, v, n, wheel[0].xyz,
- wheel[1].xyz, wheel[2].xyz ) ;
-
- /*
- * React wheel with ground.
- */
- wheelsOnGround = 0 ;
- for( i = 0 ; i < 3 ; i++ )
- {
- PFSUB_VEC3( d, wheel[i].xyz, v[i] ) ;
-
- if( PFDOT_VEC3( d, n[i] ) < 0.25f )
- {
- PFCOPY_VEC3( wheel[i].xyz, v[i] ) ;
- wheel[i].inAir = 0 ;
-
- /*
- * Adjust velocity (bounce if into ground).
- */
- sn = PFDOT_VEC3( wheel[i].vel, n[i] ) ;
- if( sn < 0.0f )
- {
- sn *= -1.1 ;
- OFFSET_VEC3( wheel[i].vel, sn, n[i] ) ;
- }
- else
- {
- PFSET_VEC3( wheel[i].vel, 0.0f, 0.0f, 0.0f ) ;
- }
- wheelsOnGround++ ;
- airBorne = 0 ;
- }
- else
- {
- wheel[i].inAir = 1 ;
- }
- }
-
- /*
- * If one wheel touches down, set velocities to zero so we don't bounce.
- */
- if( landing && wheelsOnGround )
- {
- PFSET_VEC3( wheel[FRONT_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
- PFSET_VEC3( wheel[RREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
- PFSET_VEC3( wheel[LREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
- landing = 0 ;
- }
-
- PFCOPY_VEC3( oldVel, motion.vel ) ;
-
- /*
- * Update main velocity.
- */
- motion.vel[0]= ( wheel[FRONT_WHEEL].vel[0] + wheel[RREAR_WHEEL].vel[0] +
- wheel[LREAR_WHEEL].vel[0] ) / 3.0f ;
- motion.vel[1]= ( wheel[FRONT_WHEEL].vel[1] + wheel[RREAR_WHEEL].vel[1] +
- wheel[LREAR_WHEEL].vel[1] ) / 3.0f ;
- motion.vel[2]= ( wheel[FRONT_WHEEL].vel[2] + wheel[RREAR_WHEEL].vel[2] +
- wheel[LREAR_WHEEL].vel[2] ) / 3.0f ;
-
- /*
- * Compute delta velocity components along up, right, and ahead vectors.
- */
- PFSUB_VEC3( d, motion.vel, oldVel ) ;
- vu = PFDOT_VEC3( up, d ) ;
- vr = PFDOT_VEC3( right, d ) ;
- va = PFDOT_VEC3( ahead, d ) ;
-
- /*
- * Update direction vectors.
- */
- PFSUB_VEC3( right, wheel[RREAR_WHEEL].xyz, wheel[LREAR_WHEEL].xyz ) ;
- pfNormalizeVec3( right ) ;
-
- PFCOMBINE_VEC3( u, 0.5f, wheel[RREAR_WHEEL].xyz,
- 0.5f, wheel[LREAR_WHEEL].xyz ) ;
-
- PFSUB_VEC3( ahead, wheel[FRONT_WHEEL].xyz, u ) ;
- f = -PFDOT_VEC3( ahead, right ) ;
- OFFSET_VEC3( ahead, f, right );
- pfNormalizeVec3( ahead ) ;
-
- /*
- * Smooth rotation of up vector to simulate shocks.
- */
- pfCrossVec3( u, right, ahead ) ;
- PFCOMBINE_VEC3( up, 0.60f, up, 0.40f, u ) ;
- f = -PFDOT_VEC3( up, right ) ;
- OFFSET_VEC3( up, f, right );
- pfNormalizeVec3( up ) ;
- pfCrossVec3( ahead, up, right ) ;
-
- /*
- * Update center of gravity.
- */
- motion.cg[0] = ( wheel[FRONT_WHEEL].xyz[0] + wheel[RREAR_WHEEL].xyz[0] +
- wheel[LREAR_WHEEL].xyz[0] ) / 3.0f ;
- motion.cg[1] = ( wheel[FRONT_WHEEL].xyz[1] + wheel[RREAR_WHEEL].xyz[1] +
- wheel[LREAR_WHEEL].xyz[1] ) / 3.0f ;
- motion.cg[2] = ( wheel[FRONT_WHEEL].xyz[2] + wheel[RREAR_WHEEL].xyz[2] +
- wheel[LREAR_WHEEL].xyz[2] ) / 3.0f ;
-
- /*
- * Update wheel locations relative to center of gravity.
- */
- updateWheels() ;
-
- /*
- * If up in the air, set all wheel velocities to the same value
- * to avoid the flipping-funkiness that happens otherwise.
- */
- if( wheelsOnGround == 0 && !airBorne && !landing )
- {
- airBorne = 1 ;
-
- PFCOPY_VEC3( wheel[FRONT_WHEEL].vel, motion.vel ) ;
- PFCOPY_VEC3( wheel[RREAR_WHEEL].vel, motion.vel ) ;
- PFCOPY_VEC3( wheel[LREAR_WHEEL].vel, motion.vel ) ;
- PFSCALE_VEC3( g, 0.5f, g ) ;
- if( PFDOT_VEC3( ahead, motion.vel ) < 0.0f )
- {
- PFADD_VEC3( wheel[RREAR_WHEEL].vel,
- wheel[RREAR_WHEEL].vel, g ) ;
- PFADD_VEC3( wheel[LREAR_WHEEL].vel,
- wheel[LREAR_WHEEL].vel, g ) ;
- }
- else
- {
- PFADD_VEC3( wheel[FRONT_WHEEL].vel,
- wheel[FRONT_WHEEL].vel, g ) ;
- }
- /*
- * Recalc mean velocity.
- */
- motion.vel[0]= ( wheel[FRONT_WHEEL].vel[0] +
- wheel[RREAR_WHEEL].vel[0] +
- wheel[LREAR_WHEEL].vel[0] ) / 3.0f ;
- motion.vel[1]= ( wheel[FRONT_WHEEL].vel[1] +
- wheel[RREAR_WHEEL].vel[1] +
- wheel[LREAR_WHEEL].vel[1] ) / 3.0f ;
- motion.vel[2]= ( wheel[FRONT_WHEEL].vel[2] +
- wheel[RREAR_WHEEL].vel[2] +
- wheel[LREAR_WHEEL].vel[2] ) / 3.0f ;
- }
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Modify the vehicle acceleration.
- *----------------------------------------------------------------------------*/
- void
- changeAcceleration(
- float factor
- )
- {
- accel = 2.0f * factor * accelFactor ;
- }
-
-
-
- /*------------------------------------------------------------------------------
- * Apply the brakes.
- *----------------------------------------------------------------------------*/
- void
- applyBrakes(
- void
- )
- {
- if( speed > 0.0f )
- {
- accel = -5.0f * accelFactor ;
- }
- else if( speed < 0.0f )
- {
- accel = 5.0f * accelFactor ;
- }
- else
- {
- accel = 0.0f ;
- }
- }
-